package ch.zbw.pra.sysventory.domain.scanner;

import java.util.List;

import ch.zbw.pra.sysventory.domain.model.Computer;
import ch.zbw.pra.sysventory.domain.model.Nic;
import ch.zbw.pra.sysventory.domain.model.OperatingSystem;
import ch.zbw.pra.sysventory.domain.model.Printer;
import ch.zbw.pra.sysventory.domain.model.Processor;
import ch.zbw.pra.sysventory.domain.model.Software;
import ch.zbw.pra.sysventory.domain.util.MyLogger;
import ch.zbw.pra.sysventory.ui.DetailLabel;
import ch.zbw.pra.sysventory.ui.InfoLabel;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.EnumVariant;
import com.jacob.com.Variant;

public class ScanComputer {

	private static final org.slf4j.Logger log = org.slf4j.LoggerFactory
			.getLogger(ScanComputer.class);

	// Initialise Data Types

	public String hostNameComputer;
	public String sidComputer;
	public String ramComputer;
	public String typeComputer;
	public OperatingSystem os;
	public Processor processor;
	public List<Software> softwares;
	public List<Nic> nics;
	public List<Printer> printers;

	private Computer computer;

	// Constructor
	public ScanComputer() {

	}

	// Get Coputerdata
	public Computer getComputer() {
		InfoLabel.setTextInfoLabel("Scanne Computerdaten...");
		try {
			String host = "localhost";
			String connectStr = String.format("winmgmts:\\\\%s\\root\\CIMV2", host);
			String query = "SELECT * FROM Win32_ComputerSystem";
			// Load Librarys
			ActiveXComponent axWMI = new ActiveXComponent(connectStr);

			// Execute the query
			Variant vCollection = axWMI.invoke("ExecQuery", new Variant(query));

			// Das Resultat ist eine Datensammlung
			EnumVariant enumVariant = new EnumVariant(vCollection.toDispatch());
			Dispatch item = null;
			while (enumVariant.hasMoreElements()) {
				item = enumVariant.nextElement().toDispatch();
				// Dispatch.call returns a Variant which we can convert to a
				// java
				// form.
				hostNameComputer = Dispatch.call(item, "Name").toString();
				DetailLabel.setTextDetailLabel(hostNameComputer);
				long ramTemp = Long
						.valueOf((Dispatch.call(item, "TotalPhysicalMemory")).toString())
						.longValue();

				final long MEGABYTE = 1024L * 1024L;
				ramComputer = String.valueOf(ramTemp / MEGABYTE);

				int typ = 0;
				try {
					String strTyp = Dispatch.call(item, "PCSystemType").toString();
					typ = Integer.parseInt(strTyp);
				} catch (Exception e) {
				}

				switch (typ) {
				case 0:
					typeComputer = "Unspecified";
					break;
				case 1:
					typeComputer = "Desktop";
					break;
				case 2:
					typeComputer = "Mobile";
					break;
				case 3:
					typeComputer = "Workstation";
					break;
				case 4:
					typeComputer = "Enterprise Server";
					break;
				case 5:
					typeComputer = "mall Office and Home Office (SOHO) Server";
					break;
				case 6:
					typeComputer = "Appliance PC";
					break;
				case 7:
					typeComputer = "Performance Server";
					break;
				case 8:
					typeComputer = "Maximum";
					break;
				default:
					typeComputer = "Unspecified";
					break;
				}
			}

			// SID query
			query = "SELECT * from Win32_UserAccount WHERE Name='Administrator' AND LocalAccount=True";
			vCollection = axWMI.invoke("ExecQuery", new Variant(query));
			enumVariant = new EnumVariant(vCollection.toDispatch());
			item = null;
			while (enumVariant.hasMoreElements()) {
				item = enumVariant.nextElement().toDispatch();
				sidComputer = Dispatch.call(item, "SID").toString();
				if (sidComputer.length() > 0 && sidComputer.indexOf("-") > 0) {
					sidComputer.substring(0, sidComputer.lastIndexOf("-"));
				}
			}
			InfoLabel.setTextInfoLabel("Scanne Betriebssystem...");
			ScanOperatingSystem scanOs = new ScanOperatingSystem();
			OperatingSystem os = scanOs.getOperatingSystem();

			InfoLabel.setTextInfoLabel("Scanne Prozessor...");
			ScanProcessor scanProc = new ScanProcessor();
			Processor processor = scanProc.getProcessor();

			InfoLabel.setTextInfoLabel("Scanne Software...");
			ScanSoftwares scanSoftwares = new ScanSoftwares();
			List<Software> softwares = scanSoftwares.getSoftware();

			InfoLabel.setTextInfoLabel("Scanne Netzwerkkarten...");
			ScanNic scanNics = new ScanNic();
			List<Nic> nics = scanNics.getNic();

			InfoLabel.setTextInfoLabel("Scanne Drucker...");
			ScanPrinter scanPrinter = new ScanPrinter();
			List<Printer> printers = scanPrinter.getPrinter();

			MyLogger.logDebug(log, "Host: " + hostNameComputer + " SID: " + sidComputer
					+ " RAM in MB: " + ramComputer + " Computertyp: " + typeComputer);

			computer = new Computer(hostNameComputer, sidComputer, ramComputer, typeComputer, os,
					processor, softwares, nics, printers);

		} catch (Exception e) {
			MyLogger.logError(log, e.toString());
		}
		return computer;
	}
}
